package dependency

import (
	"context"
	"gluenet/modules/manager/server/domain/entity"
	"gluenet/modules/manager/server/domain/event"
	"gluenet/modules/manager/server/domain/vo"
	"io"
)

type ConfigMetaRepo interface {
	// Get todo
	Get(ID string, userID string) (*entity.Config, error)
	// FindBy todo
	FindBy(map[string]interface{}) ([]entity.Config, error)
	FindAll() ([]entity.Config, error)
	Del(admin bool, userID string, ConfigID string) (*entity.Config, error)
	//DelAdmin(ID string) (*entity.Config, error)
	Add(req *entity.Config) (*entity.Config, error)
	Update(obj *entity.Config) error

	AddCharts(userId string, fileName string, file io.Reader) (*vo.CreateConfigReq, error)
	ImportCharts(repokey string) ([]*vo.CreateConfigReq, error)
}

type IndexRepo interface {
	Get(userId string) (*entity.Index, error)
	FindBy(map[string]string) ([]entity.Index, error)
	Del(user_id string) (*entity.Index, error)
}

type InstanceRepo interface {
	Get(GUID string, UserID string) (*entity.Instance, error)
	GetByGuid(GUID string) (*entity.Instance, error)
	FindAll() ([]entity.Instance, error)
	FindBy(map[string]interface{}) ([]entity.Instance, error)
	Add(obj *entity.Instance) (*entity.Instance, error)
	Del(GUID string, userId string) (*entity.Instance, error)
	Update(obj *entity.Instance) error
}

type DetailRepo interface {
	PutDetailKV(repoKey string, repoValue interface{}) error
	DelDetailKV(repoKey string) error
	GetByRepoKey(key string) (interface{}, error)
	Watch(repoKey string) (<-chan *event.RepoWatch, context.CancelFunc)
	GetRepoKeyOnlyWithPrefix(key string) ([]string, error)
	DeleteKeyWithPrefix(key string) error
}

type GuidCLI interface {
	Register(obj *entity.RegisterOrder) (string, error)
	UnRegister(guid string) error
}

type ScheduleCLI interface {
	Schedule(obj *entity.Instance, order *entity.ScheduleOrder) (*entity.ScheduleOrder, error)
	UnSchedule(obj *entity.ScheduleOrder) (*entity.ScheduleOrder, error)
}

type InstanceCLI interface {
	StartObject(GUID string, Runtime interface{}) error
	StopObject(GUID string, Runtime interface{}) error
	CreateObject(obj *entity.Instance, agents interface{}) (interface{}, error)
	RemoveObject(GUID string, Runtime interface{}) error
	HttpProxy(agentGuid string, url string) (interface{}, error)
	InfoStrategy(strategy string, bestApp, guarantApp []string) (interface{}, error)
}

type MetricCLI interface {
	GetInstanceState(GUID string) error
	GetInstanceMetric(obj *entity.Instance, metric string) error
	GetInstanceGraphLinkerd(obj *entity.Instance) (interface{}, error)
	GetInstanceGraphJaeger(obj *entity.Instance) (interface{}, error)
	UpdateInstanceGraphJaeger(obj *entity.Instance) error
	UpdateInstanceGraphLinkerd(obj *entity.Instance) error
	UpdateInstanceContainerMetric(obj *entity.Instance) error

	GetInstanceContainerState(GUID, container string) error
	GetInstanceContainerMetric(GUID, container, metric string) error
	GetInstanceContainerLog(GUID, container, metric string) error

	GetAgentState(GUID string) error
	GetAgentMetric(GUID, metric string) error

	GetAgentHostState(GUID, hostname string) error
	GetAgentHostMetric(GUID, hostname, metric string) error
}

type LinksRepo interface {
	Get(ID string) (obj *entity.Link, e error)
	New(obj *entity.Link) (*entity.Link, error)
	FindBy(map[string]interface{}) ([]entity.Link, error)
	Del(ControlGUID, AppGuid string) (*entity.Link, error)
	DelAll(ControlGUID string) error
}

type AgentRepo interface {
	Get(GUID string) (*entity.Agent, error)
	FindAll() ([]entity.Agent, error)
	FindBy(map[string]interface{}) ([]entity.Agent, error)
	Add(obj *entity.Agent) (*entity.Agent, error)
	Del(GUID string) (*entity.Agent, error)
	Update(obj *entity.Agent) (*entity.Agent, error)
}

type UserRepo interface {
	Get(UserID string) (obj *entity.Auth, e error)
	FindByName(proname string) (obj *entity.Auth, e error)
	FindByToken(token string) (obj *entity.Auth, e error)
	Save(obj *entity.Auth) error
	Update(obj *entity.Auth) error
	New(name string) (user *entity.Auth, e error)
}

type AreaRepo interface {
	Get(AreaID string) (*entity.Area, error)
	FindBy(map[string]interface{}) (obj []entity.Area, e error)
}

type TagRepo interface {
	Get(Id string, UserID string) (*entity.Tags, error)
	FindAll() ([]entity.Instance, error)
	FindBy(map[string]interface{}) ([]entity.Instance, error)
	Add(obj *entity.Instance) (*entity.Instance, error)
	Del(ID string) (*entity.Instance, error)
	Update(obj *entity.Instance) error
}
